package com.bjpowernode.dataservice.service;

import com.bjpowernode.api.dto.RPCResult;
import com.bjpowernode.api.model.BidInfo;
import com.bjpowernode.api.model.FinanceAccount;
import com.bjpowernode.api.model.Product;
import com.bjpowernode.api.model.User;
import com.bjpowernode.api.serivce.InvestService;
import com.bjpowernode.constants.Constant;
import com.bjpowernode.dataservice.mapper.BidInfoMapper;
import com.bjpowernode.dataservice.mapper.FinanceAccountMapper;
import com.bjpowernode.dataservice.mapper.ProductMapper;
import com.bjpowernode.dataservice.mapper.UsersMapper;
import com.bjpowernode.util.CommonUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author 麦翔盛
 * @ClassName: InvestServiceImpl
 * @Package: com.bjpowernode.dataservice.service
 * @description: 投资服务类
 * @date 2022/5/26 22:48
 */
@DubboService(interfaceClass = InvestService.class, version = "1.0")
public class InvestServiceImpl implements InvestService {

    @Resource
    UsersMapper usersMapper;

    @Resource
    ProductMapper productMapper;

    @Resource
    FinanceAccountMapper financeAccountMapper;

    @Resource
    BidInfoMapper bidInfoMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RPCResult investProduct(Integer uid, Integer pid, BigDecimal money) {
        RPCResult rpcResult = new RPCResult(false, 0, "参数错误");
        //校验用户id 和 产品id格式
        if (uid == null || pid == null || uid <= 0 || pid <= 0) {
            return RPCResult.fail(0, "用户或产品id格式错误");
        }
        //校验金额格式 是否是100的整数倍 以及是否大于100
        if (money.doubleValue() < Constant.MIN_BID_MONEY || money.doubleValue() % Constant.MIN_BID_MONEY != 0) {
            return RPCResult.fail(0, "金额必须是100的整数倍");
        }
        //查询用户是否存在
        User user = usersMapper.selectByPrimaryKey(uid);
        if (user == null) {
            return RPCResult.fail(2, "账户不存在");
        }
        //查询产品是否存在
        Product product = productMapper.selectByPrimaryKey(pid);
        if (product == null) {
            return RPCResult.fail(3, "产品不存在");
        }
        //校验用户的余额是否足够
        FinanceAccount account = financeAccountMapper.selectByUidForUpdate(uid);
        BigDecimal availableMoney = account.getAvailableMoney();
        if (!CommonUtils.ge(availableMoney, money)) {
            return RPCResult.fail(4, "账户余额不足");
        }

        //校验产品是否可以购买
        Integer status = product.getProductStatus();
        if (status != Constant.PRODUCT_STATUS_0) {
            return RPCResult.fail(5, "产品已经满标,不可以购买");
        }

        //1. 校验购买的金额是否处于购买的边界（min<=money<=max）
        //leftMoney >= money   money >= min money <= max
        BigDecimal min = product.getBidMinLimit();
        BigDecimal max = product.getBidMaxLimit();
        BigDecimal leftMoney = product.getLeftProductMoney();
        if (CommonUtils.lt(leftMoney, money) || CommonUtils.lt(money, min) || CommonUtils.lt(max, money)) {
            return RPCResult.fail(6, "购买金额无效");
        }

        //更新账户余额
        int rows = financeAccountMapper.updateMoney(uid, money);
        if (rows < 1){
            throw new RuntimeException("投资发生异常,扣除用户账户余额发生异常");
        }

        //修改理财产品剩余投资金额
        rows = productMapper.updateLeftMoney(pid, money);
        if (rows < 1) {
            throw new RuntimeException("投资发生异常,扣除理财产品剩余可投资金额发生异常");
        }

        //添加投资记录
        BidInfo bidInfo = new BidInfo();
        bidInfo.setProdId(pid);
        bidInfo.setUid(uid);
        bidInfo.setBidMoney(money);
        bidInfo.setBidTime(new Date());
        bidInfo.setBidStatus(Constant.BID_STATUS_1);
        bidInfoMapper.insertSelective(bidInfo);

        //判断是否需要修改产品的状态
        Product queryProduct = productMapper.selectByPrimaryKey(pid);
        BigDecimal newLeftMoney = queryProduct.getLeftProductMoney();

        //如果剩余金额是等于0 那么就修改产品状态
        if (CommonUtils.eq(newLeftMoney, 0.0)) {
           Product updateProduct = new Product();
           updateProduct.setId(pid);
           //修改为满标状态
           updateProduct.setProductStatus(Constant.PRODUCT_STATUS_1);
           //设置满标时间
           updateProduct.setProductFullTime(new Date());
           productMapper.updateByPrimaryKeySelective(updateProduct);
        }
        //投资成功
        return RPCResult.ok("投资成功");
    }
}









